<template>
  <div class="ol-map" id="olMap"></div>
  <!-- Popup弹窗 v-show="popupContentShow"-->
  <popup id="popup" :bridgeObj="bridgeObj" @closeWin="closeWin"></popup>
  <el-dialog :title="title" v-model="open" width="600px" append-to-body>
    <div>4444444444</div>
  </el-dialog>
</template>
<script setup>
import { ref, reactive, toRefs, onMounted, nextTick } from 'vue'
import Map from 'ol/Map' // OpenLayers的主要类，用于创建和管理地图
import View from 'ol/View' // OpenLayers的视图类，定义地图的视图属性
import { Tile as TileLayer } from 'ol/layer' // OpenLayers的瓦片图层类
import { XYZ, OSM } from 'ol/source' // OpenLayers的瓦片数据源，包括XYZ格式和OpenStreetMap专用的数据源
import { fromLonLat, toLonLat } from 'ol/proj' // OpenLayers的投影转换函数，用于经纬度坐标和投影坐标之间的转换

import {
  defaults as defaultInteractions,
  DragRotateAndZoom,
} from 'ol/interaction' // OpenLayers的交互类，包括默认的交互集合和特定的旋转缩放交互
import { defaults, FullScreen, MousePosition, ScaleLine } from 'ol/control' // OpenLayers的控件类，包括默认的控件集合和特定的全屏、鼠标位置、比例尺控件
import Feature from 'ol/Feature' // OpenLayers的要素类，表示地图上的一个对象或实体
import Point from 'ol/geom/Point' // OpenLayers的点几何类，用于表示点状的地理数据
import { Vector as VectorLayer } from 'ol/layer' // OpenLayers的矢量图层类，用于显示矢量数据
import { Vector as VectorSource } from 'ol/source' // OpenLayers的矢量数据源类，用于管理和提供矢量数据
import { Circle as CircleStyle, Style, Stroke, Fill, Icon } from 'ol/style' // OpenLayers的样式类，用于定义图层的样式，包括圆形样式、基本样式、边框、填充和图标
import LineString from 'ol/geom/LineString' // OpenLayers的线几何类，用于表示线状的地理数据
// import tb from '@/assets/image/hyfw.png'  // 导入一个图片资源
import Polygon from 'ol/geom/Polygon' // OpenLayers的多边形几何类，用于表示面状的地理数据
import Text from 'ol/style/Text'
import Circle from 'ol/style/Circle'
import Overlay from 'ol/Overlay'
import { asString } from 'ol/color'

import ping from '@/assets/images/ping.png'
import gong from '@/assets/images/gong.png'
import addMarkBg from '@/assets/images/addMarkBg.png'
import { getCurrentInstance } from 'vue'
import popup from './popup.vue'

const points = ref([])
const { proxy } = getCurrentInstance()
const open = ref(false)
const title = ref('')

const props = defineProps({
  mapList: [String, Object, Array],
})
// 监听
watch(() => props.mapList,(val) => {
    nextTick(() => {
      points.value = val
      dotMethod()
    })
  },
  { deep: true, immediate: true }
)

const data = reactive({
  bridgeObj:{}
})
const { bridgeObj } = toRefs(data);

let map = null
let overlay = null
let element = null

function initOLMap() {
  // 创造地图实例
  map = new Map({
    // 设置地图容器的ID
    target: 'olMap',
    // 定义地图的图层列表，用于显示特定的地理信息。
    layers: [
      // 高德地图
      // TileLayer表示一个瓦片图层，它由一系列瓦片（通常是图片）组成，用于在地图上显示地理数据。
      new TileLayer({
        // 设置图层的数据源为XYZ类型。XYZ是一个通用的瓦片图层源，它允许你通过URL模板来获取瓦片
        source: new XYZ({
          url: 'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
          //  url = `${url}&T=vec_c&tk={{自己的token}}`
        }),
      }),
    ],
    // 设置地图的视图参数
    // View表示地图的视图，它定义了地图的中心点、缩放级别、旋转角度等参数。
    view: new View({
      // fromLonLat是一个函数，用于将经纬度坐标转换为地图的坐标系统。
      center: fromLonLat([120.59, 30.0]), //地图中心点
      zoom: 15, // 缩放级别
      minZoom: 0, // 最小缩放级别
      maxZoom: 18, // 最大缩放级别
      constrainResolution: true, // 因为存在非整数的缩放级别，所以设置该参数为true来让每次缩放结束后自动缩放到距离最近的一个整数级别，这个必须要设置，当缩放在非整数级别时地图会糊
    }),

    // 按住shift进行旋转
    interactions: defaultInteractions().extend([new DragRotateAndZoom()]),
    // 控件
    controls: defaults().extend([
      new FullScreen(), // 全屏
      new MousePosition(), // 显示鼠标当前位置的地图坐标
      new ScaleLine(), // 显示比例尺
    ]),
  })
  // 事件
  // map.on('moveend', (e) => {
  //   console.log('地图移动', e)
  //   // 获取当前缩放级别
  //   var zoomLevel = map.getView().getZoom()
  //   console.log('当前缩放级别：', zoomLevel)
  // })
  // map.on('rendercomplete', () => {
  //   console.log('渲染完成')
  // })
  // map.on('click', (e) => {
  //   console.log('地图点击', e)
  //   var coordinate = e.coordinate

  //   // 将投影坐标转换为经纬度坐标
  //   var lonLatCoordinate = toLonLat(coordinate)
  //   // 输出转换后的经纬度坐标
  //   console.log('经纬度坐标：', lonLatCoordinate)
  // })

  //添加点击事件
  singleclick()
}

const dotMethod = () => {
  points.value.forEach((item) => {
    // 创建一个点特征（Feature）:
    let feature = new Feature({
      id:item.id,
      name: item.bridgeName,
      geometry: new Point(fromLonLat(item.center)), // 转换坐标
      src: item.bridgeType == '1' ? ping : gong,
    })
    // 设置特征样式（Style）:
    feature.setStyle(createLabelStyle(feature))
    // 创建矢量图层并添加到地图
    const vectorLayer = new VectorLayer({
      source: new VectorSource({
        features: [feature],
      }),
    })
    map.addLayer(vectorLayer)
  })
}

const repeatCanvas = document.createElement('canvas')
const repeatCtx = repeatCanvas.getContext('2d')
const img = new Image()
img.src = addMarkBg

const createLabelStyle = (feature) => {
  return new Style({
    // 使用 CircleStyle 创建一个圆形的点
    // image: new CircleStyle({ fill: new Fill({ color: 'red' }), radius: 7 }),
    // 自定义图片
    image: new Icon({
      anchor: [1, 1], // 显示位置
      scale: 0.6, //图标缩放比例
      opacity: 1, //透明度
      src: feature.get('src'),
    }),
    //文字样式信息
    text: new Text({
      textAlign: 'center', //对齐方式
      textBaseline: 'middle', //文本基线
      font: 'normal 12px 微软雅黑', //字体样式
      text: feature.get('name'), //文本内容
      offsetX: -15,
      offsetY: -60, // Y轴偏置
      // fill: new Fill({
      //   color: asString([0, 0, 0, 0.6]),
      // }), //填充样式
      backgroundFill: new Fill({
        color: repeatCtx.createPattern(img, 'repeat')
      }), // 填充背景
      padding: [6, 6, 6, 6],
    })
  })
}

const singleclick = () => {
  map.on('click', (e) => {
    const coordinate = e.coordinate
    // 获取渲染的点携带的参数信息
    const feature = map.forEachFeatureAtPixel(e.pixel, feature => feature)
    if ((feature ?? '') !== '' && (feature ?? '') !== '') { //点击桥梁处携带的数据
      var coordinates = feature.getGeometry().getCoordinates();
      //自定义弹框
      // title.value = feature.values_.name
      // open.value = true
      // 点击弹框overlay
      setDIYmarkers(coordinates,feature.values_)
    } else { // 底图点击处携带的数据
      // console.log('点击了地图底图')
      // DrawMethod()
    }
  })
}

//new Overlay 弹框
function setDIYmarkers(coordinate, feature) {
  const obj = points.value.find(item => item.id === feature.id)
  bridgeObj.value = obj

  element = document.getElementById('popup')
  overlay = new Overlay({
    element,
    autoPan: true,
    positioning: 'bottom-center',
    stopEvent: false,
    offset: [0, -50],
    //是否应该停止事件传播到地图窗口
    stopEvent: false,
    autoPanAnimation: {
      //当Popup超出地图边界时，为了Popup全部可见，地图移动的速度
      duration: 250
    }
  });
  overlay.setPosition(coordinate);
  map.addOverlay(overlay)
}
const closeWin = () => {
  overlay.setPosition(undefined);
  return false;
}

const DrawMethod = () => {
  // 创建一个绘制交互（Draw）
  // 监听地图上的鼠标点击事件
  map.on('click', function (event) {
    console.log('点击了地图', event)

    // 获取点击位置的坐标
    let coordinate = event.coordinate

    // 创建点特征（Feature）
    let pointFeature = new Feature({
      geometry: new Point(coordinate),
    })

    // 设置点特征的样式（Style）
    pointFeature.setStyle(
      new Style({
        image: new CircleStyle({
          fill: new Fill({
            color: 'red', // 点的填充颜色为红色
          }),
          radius: 7, // 点的半径
          stroke: new Stroke({
            color: 'black', // 点的边界颜色为黑色
            width: 2, // 点的边界宽度
          }),
        }),
      })
    )

    // 创建和添加特征到源（Source）
    let source = new VectorSource()
    source.addFeature(pointFeature)

    // 创建图层并设置源（Layer）
    let layer = new VectorLayer()
    layer.setSource(source)

    // 将图层添加到地图上
    map.addLayer(layer)
  })
}

onMounted(() => {
  // 地图初始化
  initOLMap()
})
</script>

<style scoped>
.ol-map {
  height: calc(100vh - 84px);
}
</style>
